//
//  BALRequestServiceManager.m
//  BALPractice
//
//  Created by zhuhao on 15/3/6.
//  Copyright (c) 2015年 zhuhao. All rights reserved.
//

#import "BALRequestServiceManager.h"
#import <AFNetworking.h>
#import <CommonCrypto/CommonDigest.h>
#import "BALBaseRequestEntity.h"

@implementation BALRequestServiceManager

#pragma mark -
#pragma mark - Public

+(instancetype)shareServiceManager{
    
    static BALRequestServiceManager *s_serviceManager = nil;
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        s_serviceManager = [[BALRequestServiceManager alloc]init];
    });
    
    return s_serviceManager;
}

-(void)requestWithEntity:(BALBaseRequestEntity *)requestEntity{
    
    switch (requestEntity.requestMethod) {
        case RequestMethodTypeGet:
            
            [self httpGetRequestWithRequestEntity:requestEntity];
            
            break;
            
        case RequestMethodTypePost:
            
            [self httpPostRequestWithRequestEntity:requestEntity];
            
            break;
        default:
            break;
    }
}

#pragma mark -
#pragma mark - private

-(instancetype)init{
    self = [super init];
    if (self) {
        
    }
    return self;
}

-(void)httpGetRequestWithRequestEntity:(BALBaseRequestEntity*)requestEntity{
    
    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:requestEntity.urlPath parameters:requestEntity.params error:nil];
    request.timeoutInterval = requestEntity.timeout;
    
    AFHTTPRequestOperationManager *requestManager = [AFHTTPRequestOperationManager manager];
    requestManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
    
    AFHTTPRequestOperation *requestOperation = [requestManager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        
        [requestEntity createDataModelWithResponseData:responseObject];
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        
    }];
    
    requestEntity.currentRequestOperation = requestOperation;
    [requestOperation start];
}

-(void)httpPostRequestWithRequestEntity:(BALBaseRequestEntity*)requestEntity{
    
    [BALRequestServiceManager c_sign:requestEntity.params md5Key:@"bfd87d38d99408f7058287f663f9ddf8" signKey:@"sig"];
    
    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:requestEntity.urlPath parameters:requestEntity.params error:nil];
    request.timeoutInterval = requestEntity.timeout;
    
    AFHTTPRequestOperationManager *requestManager = [AFHTTPRequestOperationManager manager];
    //requestManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
    
    AFHTTPRequestOperation *requestOperation = [requestManager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        
       
        [requestEntity createDataModelWithResponseData:responseObject];
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"%@",error);
    }];
    
    requestEntity.currentRequestOperation = requestOperation;
    [requestOperation start];
}

+ (NSString *)c_sign:(NSMutableDictionary *)dicParams md5Key:(NSString *)md5Key signKey:(NSString *)signKey
{
    NSMutableString *retStr = [NSMutableString stringWithString:@""];
    if (dicParams ? dicParams.count > 0 : NO)
    {
        NSMutableString *sigStr = [NSMutableString stringWithString:@""];
        BOOL isSign = NO;
        BOOL isFirst = YES;
        NSArray *arr = [[dicParams allKeys] sortedArrayUsingSelector:@selector(compare:)];
        for (NSString *key in arr)
        {
            id idValue = dicParams[key];
            NSString *value = nil;
            if ([idValue isKindOfClass:[NSString class]])
            {
                value = idValue;
            }
            else if ([idValue isKindOfClass:[NSNumber class]])
            {
                value = [idValue stringValue];
            }
            if ([value isKindOfClass:[NSString class]])
            {
                if ([key isEqualToString:@"sig"])
                {
                    isSign = YES;
                }
                else
                {
                    [sigStr appendFormat:@"%@=%@", key, value];
                }
                if (isFirst)
                {
                    isFirst = NO;
                }
                else
                {
                    [retStr appendFormat:@"&"];
                }
                [retStr appendFormat:@"%@=%@", key, [self c_encodeToPercentEscapeString:value]];
            }
        }
        if (!isSign)
        {
//            PGMD5 *pgMD5 = [[PGMD5 alloc] init];
            NSString *strSig = [self MD5:sigStr key:md5Key encode:NSUTF8StringEncoding];//[pgMD5 MD5:sigStr key:md5Key encode:NSUTF8StringEncoding];
            // #warning 签名使用得是万能签名，发包时必须更改成正常签名 e5ac3ecc1b462d7aa357faf24981c0ab 万能密码
            //            {
            //                strSig = @"e5ac3ecc1b462d7aa357faf24981c0ab";
            //            }
            dicParams[signKey] = strSig;
            [retStr appendFormat:@"&%@=%@", signKey, strSig];
        }
    }
    return retStr;
}

+ (NSString *)c_encodeToPercentEscapeString:(NSString *)input
{
    // Encode all the reserved characters, per RFC 3986
    // (<http://www.ietf.org/rfc/rfc3986.txt>)
    if ([input isKindOfClass:[NSString class]])
    {
        CFStringRef stringRef = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                        (__bridge CFStringRef)input, NULL,
                                                                        (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                        kCFStringEncodingUTF8);
        NSString *outputStr = CFBridgingRelease(stringRef);
        return outputStr;
    }
    return input;
}

+ (NSString *)MD5:(NSString *)orgStr key:(NSString *)key encode:(NSStringEncoding)encode
{
    NSMutableString *outStr = [[NSMutableString alloc] initWithCapacity:10];
    
    const char *keyBytes = NULL;
    NSUInteger len = 0;
    if (key != nil&& [key length] > 0)
    {
        NSData *data = [key dataUsingEncoding:encode];
        len = [data length];
        keyBytes = [key UTF8String];
    }
    unsigned char *md5CStr = [self _md5:orgStr];
    int leno = 16;
    Byte ch, ch1, ch2;
    for (int i = 0; i < leno; i++)
    {
        if (keyBytes != NULL)
        {
            ch1 = md5CStr[i];
            ch2 = keyBytes[i % len];
            ch = (Byte)(ch1 ^ ch2);
        }
        else
        {
            ch = md5CStr[i];
        }
        [outStr appendFormat:@"%02x", ch];
    }
    free(md5CStr);
    return outStr;
}

+ (unsigned char *)_md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    //    unsigned char *md5 = (unsigned char*)[iStr UTF8String];
    unsigned char *md5 = (unsigned char *)malloc(1024);
    memset(md5, 0, 1024);
    CC_MD5(cStr, (unsigned int)strlen(cStr), md5);
    
    return md5;
}

@end
